/**
 * @Author Yunfeng Bai
 *
 * 2010-10-30
 */
package collision;

import geometry.Drawable;
import geometry.ObjModel;
import geometry.Triangle;
import geometry.TriangleMesh;
import geometry.TriangleMesh.TriangleIndex;

import java.util.ArrayList;
import java.util.List;

import javax.media.opengl.GL2;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public class BoundingSphere extends BoundingVolume
{
    public Drawable _object;
    public Point3d _origin;
    public double _radius;
    
    private Matrix4d toModelSpace = new Matrix4d();

    /**
     * Create a sphere bounding box with designated origin and radius.
     */
    public BoundingSphere(Drawable object_, Point3d origin_, double radius_)
    {
        _object = object_;
        _origin = origin_;
        _radius = radius_;
        toModelSpace.setIdentity();
    }

    /**
     * Create a sphere bounding box corresponding to an object model.
     */
    public BoundingSphere(Drawable object_, ObjModel model_)
    {
        _object = object_;
        BoundingBox bbox = model_.getBoundingBox();
        _origin = new Point3d();
        _origin.interpolate(bbox._minPt, bbox._maxPt, 0.50);
        _radius = bbox._maxPt.distanceLinf(bbox._minPt);
        toModelSpace.setIdentity();
    }
    
    public BoundingSphere clone()
    {
    	BoundingSphere sphere = new BoundingSphere(_object, (Point3d)_origin.clone(), _radius);
    	return sphere;
    }

	public void update(Matrix4d newToWorldSpaceMatrix)
	{
    	Matrix4d t = new Matrix4d();
		t.mul(newToWorldSpaceMatrix, toModelSpace);
		t.transform(_origin);
		
		toModelSpace.invert(newToWorldSpaceMatrix);
	}

	@Override
	public boolean isColliding(BoundingVolume obj_)
	{
		if ((obj_ instanceof BoundingSphere) == false)
            throw new IllegalArgumentException(
                    "BoundingSphere can only collide with BoundingSphere");

        BoundingSphere sph = (BoundingSphere) obj_;
        double d = _origin.distance(sph._origin);
        
        return d <= _radius + sph._radius;
	}

	@Override
	public void build(GL2 gl)
	{
		throw new NotImplementedException();
	}

	@Override
	public TriangleMesh getTriangleMesh()
	{
		throw new NotImplementedException();
	}

	@Override
	public BoundingBox getBoundingBox()
	{
		// No need to get the bounding box of a BoundingSphere.
		throw new NotImplementedException();
	}
}
